<?php

/**
 * Created by PhpStorm.
 * User: liamu
 * Date: 2017/12/13
 * Time: 10:17
 * 定义游戏规则配置数据格式如下
 */
class ThirteenWater {
	/**
     * @var array|初始化纸牌数据
     */
    private $cards = array();
    private $game_type=[1=>'经典玩法',2=>'刀刀玩法',3=>'特殊牌型'];
    private $banker_mode=[1=>'通比模式',2=>'庄家模式'];
    private $color=['A'=>'方片','B'=>'草花','C'=>'红桃','D'=>'黑桃'];//黑桃＞红桃＞草花＞方片
    /**
     * douniu constructor.
     * 构造函数
     * @param $cards  初始化纸牌数据
     */
    public function __construct($cards = array()) {
        if (empty($cards)) {
            $cards = "A101,A102,A103,A104,A105,A106,A107,A108,A109,A110,A111,A112,A113,B101,B102,B103,B104,B105,B106,B107,B108,B109,B110,B111,B112,B113,C101,C102,C103,C104,C105,C106,C107,C108,C109,C110,C111,C112,C113,D101,D102,D103,D104,D105,D106,D107,D108,D109,D110,D111,D112,D113";
            //生成数组
            $this->cards = explode(",", $cards);
            //将52张牌的顺序打乱，相当于洗牌
            shuffle($this->cards);
        } else {
            $this->cards = $cards;
        }
    }
    /**
     * 发牌
     * @param  [int] $playerCount [选手人数]
     * @return [bool] false |  [array]    [牌的数组]
     */
    public function create($playerCount) {
        if($playerCount<0 or $playerCount>4){
            return false;
        }
        $array = $this->cards;
        $allCount = $playerCount * 13;
        for ($i = 0; $i < $allCount; $i++) {
            $paiInfo[floor($i / 13)][] = $array[$i];
        }
        return $paiInfo;
    }
    public function test(){
        $cards_str='A101,A102,A103,A104,A105,A106,A107,A108,A109,A110,A111,A112,A113';
        $cards=explode(',',$cards_str);
        $ColorsNums=$this->getColorsNums($cards);
        $ret=$this->isSanTongHuaShun($cards);
        var_dump($ret);
    }
    /**
     * 判断牌的花和颜色是否相同
     * @param  [array]  $colors [牌的花色数组]
     * @return boolean false|true  [是否同种花色]
     */
    private function isSameShapColor($colors){
        if(is_array($colors)){
            $firstColor=$colors[0];
            foreach ($colors as $color) {
                if($firstColor !=$color){
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    /**
     * 判断是不是顺子
     * @param  [array]  $nums [数字大小数组]
     * @return boolean   false | true
     */
    private function isStraight($nums){
        if(is_array($nums)){
            sort($nums);
            // 循环取出数字，和下一个比大小
            foreach ($nums as $key=> $num) {
                if(isset($nums[$key+1])){
                    if(($num + 1)==$nums[$key+1])continue;
                    return false;
                }else{
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 获取一张牌的花色和大小
     * @param  [string] $oneCard [牌]
     * @return [bool] false  | [array]   [0=>'花色',1=>'大小']
     */
    private function getColorNum($oneCard){
        $oneCard=trim($oneCard);
        if(count($oneCard) <1){
            return false;
        }
        $color=substr($oneCard, 0,1);
        $num=(int)substr($oneCard,1);
        if(!in_array($color,['A','B','C','D']))return false;
        if($num<101 or $num>113) return false;
        return ['color'=>$color, 'num'=>$num ];
    }
    /**
     * 返回顺子的组数
     * @param  [array] $nums [牌]
     * @return [array]       [顺子的数组]
     */
    private function getStraights($nums){
        $cards=[];
        $k=0;
        foreach ($nums as $key => $num) {
            $cards[$k][]=$num;
            if(isset($nums[$key+1])){
                if(($num+1)!=$nums[$key+1]) $k++;
            }
        }
        return $cards;
    }
    /**
     * 得到一组牌的花色数组和数字数组
     * @param  [array] $cards [一组牌]
     * @return [bool] false |array  [花色数组,数字大小数组]
     */
    private function getColorsNums($cards){
        if(is_array($cards)){
            $colors=[];
            $nums=[];
            $tem_arr=[];
            foreach ($cards as $card) {
                $tem_arr=$this->getColorNum($card);
                if($tem_arr){
                    $colors[]=$tem_arr['color'];
                    $nums[]=$tem_arr['num'];
                }else{
                    return false;
                }
            }
            return ['colors'=>$colors,'nums'=>$nums];
        }
        return false;
    }
    /**
     * 三顺子
     * 三墩分别是顺子
     * @param  [type]  $cards [牌]
     * @return boolean  false | true
     */
    private function isSanShunZi($cards){
        
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!(isset($cards['nums']) and count($cards['nums'])==13))return false;

    }
    /**
     * 三同花
     * 三墩的花色分别相同
     * @param  [type]  $cards [牌]
     * @return boolean  false | true
     */
    private function isSanTonghua($cards){
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!(isset($cards['colors']) and count($cards['colors'])==13))return false;
        $shapColors=array_count_values($cards['colors']);
        foreach ($shapColors as $key => $val) {
            if(in_array($val,[3,5,8,10,13]))continue;
            return false;
        }
        return true;
    }
    /**
     * 六对半
     * 六个对子加一个单张
     * @param  [type]  $cards [牌]
     * @return boolean  false | true
     */
    private function isLiuDuiBan($cards){
       $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!(isset($cards['nums']) and count($cards['nums'])==13))return false;
        // 取出牌数字重复的次数
        $cards_nums=array_count_values($cards['nums']);
        $santiao=0;
        $duizi=0;
        foreach ($cards_nums as $key => $val) {
            if($val===2){
                ++$duizi;
            }elseif($val==3){
                ++$santiao;
            }elseif($val==4){//四张相同就是两对
                $duizi+=2;
            }
        }
        if($duizi==5 && $santiao==1)return true;
        return false; 
    }
    /**
     * 五对三条
     * 判断是否是5个对子，一个三条
     * @param  [type]  $cards [牌]
     * @return boolean  false | true
     */
    private function isWuduiSanTiao($cards){
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!(isset($cards['nums']) and count($cards['nums'])==13))return false;
        // 取出牌数字重复的次数
        $cards_nums=array_count_values($cards['nums']);
        $santiao=0;
        $duizi=0;
        foreach ($cards_nums as $key => $val) {
            if($val===2){
                ++$duizi;
            }elseif($val==3){
                ++$santiao;
            }elseif($val==4){
                $duizi+=2;
            }
        }
        if($duizi==5 && $santiao==1)return true;
        return false;
    }
    /**
     * 四套三条
     * 判断是否是四个三条余一张
     * @param  [type]  $cards [牌]
     * @return boolean  false | true
     */
    private function isSiTaoSanTiao($cards){
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!(isset($cards['nums']) and count($cards['nums'])==13))return false;
        // 取出牌数字重复的次数
        $cards_nums=array_count_values($cards['nums']);
        // 如果不是5组就返回错误
        if(count($cards_nums)!=5)return false;
        $santiao=0;
        $danzhang=0;
        foreach ($cards_nums as $val) {
            if($val===3){
                ++$santiao;
            }elseif($val==1){
                ++$danzhang;
            }
        }
        if($santiao==4 and $danzhang==1)return true;
        return false;
    }
    /**
     * 判断是否是凑一色（13张颜色相同（红色或黑色） 红桃 方块 或 黑桃梅花）
     * @param  [type]  $cards [牌]
     * @return boolean  false | true
     */
    private function isCouYiSe($cards){
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!isset($cards['colors']) or count($cards['colors'])!=13)return false;
        $shapColors=array_count_values($cards['colors']);
        //如果花色大于2种（红桃方块   或者 黑桃梅花），肯定不是同色返回false
        if(count($shapColors)>2)return false;
        $red=0;
        $black=0;
        foreach ($shapColors as $key => $val) {
            if(in_array($key,['A','C'])){
                ++$red;
            }elseif(in_array($key,['B','D'])){
                ++$black;
            }
        }
        if($red>1 or $black>1)return true;
        return false;
    }
    /**
     * [判断是不是全小]
     * @param  [array]  $cards [牌]
     * @return boolean  false | true
     */
    private function isQuanXiao($cards){
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!isset($cards['nums']))return false;
        foreach ($cards['nums'] as $card) {
            if(in_array($card,[2,3,4,5,6,7,8]))continue;
            return false;
        }
        return true;
    }
    /**
     * [判断是不是全大]
     * @param  [array]  $cards [牌]
     * @return boolean  false | true
     */
    private function isQuanDa($cards){
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!isset($cards['nums']))return false;
        foreach ($cards['nums'] as $card) {
            if(in_array($card,[1,8,9,10,11,12,13]))continue;
            return false;
        }
        return true;
    }
    /**
     * [判断是不是三个炸弹加一张零牌]
     * @param  [type]  $cards [牌数组]
     * @return boolean  false | true
     */
    private function isSanZhadan($cards){
        //获取牌型的数字和花色
        $cards=$this->getColorsNums($cards);
        //验证获取的牌数字是否存在
        if(!$cards)return false;
        if(!isset($cards['nums']))return false;

        $cards_nums=array_count_values($cards['nums']);
        //判断不是是4组相同（三个炸弹,1张零牌），返回false
        if(count($cards_nums) !=4)return false;
        foreach ($cards_nums as $key => $val) {
            if(in_array($val,[4,1])){
                continue;
            }else{
                return false;
            }
        }
        return true;
    }
    /**
     * 是否是三同花顺
     * @param  [array]  $cards [散乱的牌]
     * @return boolean  false | true
     */
    private function isSanTongHuaShun($cards){
        $key_value=['A101'=>101,'A102'=>102,'A103'=>103,'A104'=>104,'A105'=>105,'A106'=>106,'A107'=>107,'A108'=>108,'A109'=>109,'A110'=>110,'A111'=>111,'A112'=>112,'A113'=>113,'A114'=>114,'B101'=>201,'B102'=>202,'B103'=>203,'B104'=>204,'B105'=>205,'B106'=>206,'B107'=>207,'B108'=>208,'B109'=>209,'B110'=>210,'B111'=>211,'B112'=>212,'B113'=>213,'B114'=>214,'C101'=>301,'C102'=>302,'C103'=>303,'C104'=>304,'C105'=>305,'C106'=>306,'C107'=>307,'C108'=>308,'C109'=>309,'C110'=>310,'C111'=>311,'C112'=>312,'C113'=>313,'C114'=>314,'D101'=>401,'D102'=>402,'D103'=>403,'D104'=>404,'D105'=>405,'D106'=>406,'D107'=>407,'D108'=>408,'D109'=>409,'D110'=>410,'D111'=>411,'D112'=>412,'D113'=>413,'D114'=>414];
        
        sort($cards);
        $cards_str=implode($cards, ',');
        var_dump($cards_str);
        var_dump(strpos($cards_str, 'A101'));
        var_dump(strpos($cards_str,'A110,A111,A112,A113'));
        if(strpos($cards_str, 'A101')!==false && strpos($cards_str,'A110,A111,A112,A113')!==false ){
            $key=array_search('A101',$cards);
            unset($cards[$key]);
            array_push($cards, 'A114');
        }
        var_dump($cards);die;
        $card_values=[];
        foreach ($cards as $card) {
            $card_values[]=$key_value[$card];
        }
        sort($card_values);
        $cards_arr=$this->getStraights($card_values);
        //同花顺的组数必须不能大于3组
        if(count($cards_arr)>3)return false;
        // 同花顺每组符合 头墩3张，中墩5张，尾墩5张
        foreach ($cards_arr as  $val) {
            if(in_array(count($val),[3,5,10,8,13])){
                continue;
            }else{
                return false;
            }
        }
        return true;
    }
    /**
     * 是否是十二皇族（第二大）
     * @param  [array]  $cards [牌花色和数字数组]
     * @return boolean  false |true
     */
    private function isShiErHuangZu($cards){
        if(!isset($cards['nums']))return false;
        $nums=$cards['nums'];
        if(count($nums)<13) return false;
        $royalty=[101,111,112,113];
        foreach ($nums as $num) {
            if(in_array($num,$royalty)){
                continue;
            }else{
                return false;
            }
        }
        return true;
    }
    /**
     * 是否是至尊青龙(最大)
     * @param  [array]  $cards [牌花色和数字数组]
     * @return boolean  true|false  array
     */
    private function isZhiZunQingLong($cards){
        if(!(isset($cards['nums']) && isset($cards['colors']))) return false;
        $nums=$cards['nums'];
        $colors=$cards['colors'];
        if(count($nums)<13) return false;
        //判断是否是同花色和顺子
        if($this->isSameShapColor($colors) && $this->isStraight($nums)){
            return true;
        }
        return false;
    }
}